package edu.xhu.behavior.config;

import cn.hutool.core.collection.CollUtil;
import edu.xhu.model.im.constant.IMRedisKey;
import edu.xhu.model.im.enums.IMTerminalType;
import edu.xhu.model.im.pojos.IMUserInfo;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.*;

@Configuration
@AllArgsConstructor
public class IMClient {

    private final StringRedisTemplate redisTemplate;

    /**
     * 判断用户是否在线
     *
     * @param userId 用户id
     */
    public Boolean isOnline(Long userId) {
        String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, userId.toString(), "*");
        return !Objects.requireNonNull(redisTemplate.keys(key)).isEmpty();
    }

    /**
     * 判断多个用户是否在线
     *
     * @param userIds 用户id列表
     * @return 在线的用户列表
     */
    public List<Long> getOnlineUser(List<Long> userIds) {
        return new LinkedList<>(getOnlineTerminal(userIds).keySet());
    }

    public Map<Long, List<IMTerminalType>> getOnlineTerminal(List<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return Collections.emptyMap();
        }
        // 把所有用户的key都存起来
        Map<String, IMUserInfo> userMap = new HashMap<>();
        for (Long id : userIds) {
            for (Integer terminal : IMTerminalType.codes()) {
                String key = String.join(":", IMRedisKey.IM_USER_SERVER_ID, id.toString(), terminal.toString());
                userMap.put(key, new IMUserInfo(id, terminal));
            }
        }
        // 批量拉取
        List<String> serverIds = redisTemplate.opsForValue().multiGet(userMap.keySet());
        Map<Long, List<IMTerminalType>> onlineMap = new HashMap<>();
        if (serverIds != null && !serverIds.isEmpty()) {
            int idx = 0;
            for (Map.Entry<String, IMUserInfo> entry : userMap.entrySet()) {
                // serverid有值表示用户在线
                if (serverIds.get(idx++) != null) {
                    IMUserInfo userInfo = entry.getValue();
                    List<IMTerminalType> terminals = onlineMap.computeIfAbsent(userInfo.getId(), o -> new LinkedList<>());
                    terminals.add(IMTerminalType.fromCode(userInfo.getTerminal()));
                }
            }
        }
        // 去重并返回
        return onlineMap;
    }


}
